package com.yuxl.common.core.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * Long 转 String 序列化器
 * 用于解决前端 JavaScript 处理大整数时的精度丢失问题
 * @author yuxl
 */
public class LongToStringSerializer extends JsonSerializer<Object> {

    // JavaScript 安全整数范围: ±9007199254740991 (2^53-1)
    private static final BigInteger MAX_SAFE_INTEGER = BigInteger.valueOf(9007199254740991L);
    private static final BigInteger MIN_SAFE_INTEGER = BigInteger.valueOf(-9007199254740991L);

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (value == null) {
            gen.writeNull();
            return;
        }

        BigInteger number;

        if (value instanceof BigInteger) {
            number = (BigInteger) value;
        } else if (value instanceof BigDecimal) {
            number = ((BigDecimal) value).toBigInteger();
        } else if (value instanceof Long) {
            number = BigInteger.valueOf((Long) value);
        } else if (value instanceof Integer) {
            // 整数范围安全，直接输出
            gen.writeNumber((Integer) value);
            return;
        } else {
            // 其他数字类型，转换为字符串
            gen.writeString(value.toString());
            return;
        }

        // 判断是否超出安全范围
        if (number.compareTo(MAX_SAFE_INTEGER) > 0 || number.compareTo(MIN_SAFE_INTEGER) < 0) {
            gen.writeString(number.toString());
        } else {
            gen.writeNumber(number.toString());
        }
    }
} 